#include "drv_eth.h"
#include "Ifx_Lwip.h"
#include "Configuration.h"
#include "IfxGeth_reg.h"
#include "cc.h"
#include "drv_stm.h"
#include "drv_led.h"
#include "port.h"
#include "srv_threads.h"
xSemaphoreHandle s_xSemaphore;

boolean _is_lwip_initiallized = FALSE;
void drv_geth_init(void)
{
    extern boolean _b_is_uart_initiallized;
    while(!_b_is_uart_initiallized);

        IfxGeth_enableModule(&MODULE_GETH);                     /* Enable Gigabit Ethernet Media Access Controller (GETH) module*/

        /* Define a MAC Address */
        eth_addr_t ethAddr;
        ethAddr.addr[0] = 0xAD;
        ethAddr.addr[1] = 0xDD;
        ethAddr.addr[2] = 0xDD;
        ethAddr.addr[3] = 0xDD;
        ethAddr.addr[4] = 0xDD;
        ethAddr.addr[5] = 0xDA;

        Ifx_Lwip_init(ethAddr);
        _is_lwip_initiallized = TRUE;
}



void increase_g_TickCount_1ms_isr(void)
{
    g_TickCount_1ms++;
}


void vTimerISR( xSemaphoreHandle  xSemaphore )
{
static uint8_t ucLocalTickCount = 0;
static BaseType_t xHigherPriorityTaskWoken;
 // A timer tick has occurred.
 // ... Do other time functions.
 // Is it time for vATask () to run?
 xHigherPriorityTaskWoken = pdFALSE;
 ucLocalTickCount++;
 if( ucLocalTickCount >= TICKS_TO_WAIT )
 {
     // Unblock the task by releasing the semaphore.
     xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
     // Reset the count so we release the semaphore again in 10 ticks time.
     ucLocalTickCount = 0;
 }
 if( xHigherPriorityTaskWoken != pdFALSE )
 {
     prvYield_GETH_ISR(xHigherPriorityTaskWoken);
     // We can force a context switch here.  Context switching from an
     // ISR uses port specific syntax.  Check the demo task for your port
     // to find the syntax required.
 }
}

void ISR_Geth_Tx()
{
    extern uint32 isrTxCount;
    isrTxCount++;
//    Ifx_Lwip_printf("sending eth");
}
void ISR_Geth_Rx()
{
    BaseType_t xHigherPriorityTaskWoken;
    extern uint32_t get_xhandle_itemsize();
    if(get_xhandle_itemsize()!=0)
    {
        Ifx_Lwip_printf("ISR_Geth_Rx!!!!!!");
    }
    extern uint32 isrRxCount;
    isrRxCount++;
#if !NO_SYS
    xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
    if( xHigherPriorityTaskWoken != pdFALSE )
    {
        prvYield_GETH_ISR(xHigherPriorityTaskWoken);
    }
#endif
}


IFX_INTERRUPT(ISR_Geth_Tx, CPU_WHICH_SERVICE_ETHERNET, ISR_PRIORITY_GETH_TX);
IFX_INTERRUPT(ISR_Geth_Rx, CPU_WHICH_SERVICE_ETHERNET, ISR_PRIORITY_GETH_RX);

void drv_geth_ctl_status(void)
{
    if(!_is_lwip_initiallized)
    {
        return;
    }
    Ifx_GETH_MAC_PHYIF_CONTROL_STATUS ctrl_status;
    ctrl_status.U = GETH_MAC_PHYIF_CONTROL_STATUS.U;
    static boolean linkup = FALSE;
    if (ctrl_status.B.LNKSTS == 0)
    {
        if(linkup)
        {
            Ifx_Lwip_printf("cnet lost");
        }
        netif_set_link_down(&g_Lwip.netif);
        drv_led3_h();
        linkup = FALSE;
    }
    else {
        if(linkup)return;

        Ifx_Lwip_printf("cnet suc");
        IfxGeth_Eth *ethernetif = g_Lwip.netif.state;
        // we set the correct duplexMode
        if (ctrl_status.B.LNKMOD == 1)
            IfxGeth_mac_setDuplexMode(ethernetif->gethSFR, IfxGeth_DuplexMode_fullDuplex);
        else
            IfxGeth_mac_setDuplexMode(ethernetif->gethSFR, IfxGeth_DuplexMode_halfDuplex);
        // we set the correct speed
        if (ctrl_status.B.LNKSPEED == 0)
            // 10MBit speed
            IfxGeth_mac_setLineSpeed(ethernetif->gethSFR, IfxGeth_LineSpeed_10Mbps);
        else
            if (ctrl_status.B.LNKSPEED == 1)
                // 100MBit speed
                IfxGeth_mac_setLineSpeed(ethernetif->gethSFR, IfxGeth_LineSpeed_100Mbps);
            else
                // 1000MBit speed
                IfxGeth_mac_setLineSpeed(ethernetif->gethSFR, IfxGeth_LineSpeed_1000Mbps);
        netif_set_link_up(&g_Lwip.netif);
        drv_led3_l();
        linkup = TRUE;
    }
}

//void ETH_IRQHandler(void)
//{
//    uint32_t ulReturn;
//    /* 进入临界段，临界段可以嵌套 */
//    ulReturn = taskENTER_CRITICAL_FROM_ISR();
//    HAL_ETH_IRQHandler(&heth);
//    /* 退出临界段 */
//    taskEXIT_CRITICAL_FROM_ISR( ulReturn );
//}
//
//
//
//extern xSemaphoreHandle s_xSemaphore;
//void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
//{
//    // LED2_TOGGLE;
//    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
//    xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
//    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
//}




